/**
 * MySurfaceInfo.java
 * 版权所有(C) 2014
 * 创建者:cuiran 2014-7-22 上午9:59:32
 */
package com.ghyf.mplay.bean;



import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

import com.ghyf.mplay.WeakHandler;
import com.ghyf.mplay.application.CookieConstants;
import com.ghyf.mplay.application.UserInfoSingleton;
import com.ghyf.mplay.datatype.POS;

import com.ghyf.mplay.net.common.RecvBase;
import com.ghyf.mplay.uimanager.ViewManager;
import com.ghyf.mplay.util.LogUtil;
import com.ghyf.mplay.value.ConstantValue;
import com.ghyf.mplay.view.MVideoLive;

/**
 * 播放直播视频模块的信息类 
 * @author cuiran
 * @version 1.0.0
 */
public class VideoSurfaceInfo extends BaseModuleInfo {
	  private static final String TAG="VLC/VideoSurfaceInfo";
	  private MVideoLive surfaceView=null;
	  private Thread receiveThread=null;
	  /**开启UDP组播**/
	  private static final int CMD_OPEN_UDP = 0;
	  /**检测UDP组播**/
	  private static final int CMD_CHECK_UDP = 1;
	  /**检测全局变量**/
	  private static final int CMD_CHECK_PARAM = 2;

	  private AudioManager mAudioManager;
	  private int max;
	  
	  private boolean isLive; // 是否直播
	  // <Live_Channel>LiveChannel1(239.1.1.2:2860)</Live_Channel>
	  private String live_channel;
	  // <Live_Volume>>50</Live_Volume >
	  private int live_volume=50; // 直播音量
	  private String live_url;
	  private Context mContext=null;
	  private static VideoSurfaceInfo instance =null;
	  public static boolean isStop=false;
	    
	    public static VideoSurfaceInfo getInstance(){
	    	if(instance ==null){
	    		instance=new VideoSurfaceInfo();
	    	}
	    	return instance;
	    }
	@Override
	public MVideoLive getView(Context context) {
		mContext=context;
//		surfaceView=MVideoLive.getInstance(context);
		surfaceView=new MVideoLive(context);
		///sata/media/jiuzai.mpg
		//udp://@239.1.1.0:1234 
		// 设置控件的位置
		initPosition(surfaceView, pos);
		mAudioManager = (AudioManager) context
				.getSystemService(Context.AUDIO_SERVICE);
		max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		
		
		return surfaceView;
	}
	
	
	/**
	 * 开始直播<br>
	 * 2014-8-11 下午12:29:28
	 *
	 */
	public void startPlay(){
		try{
			isStop=false;
			surfaceView.initVideoView();
			// 设置音量
			boolean isSet=UserInfoSingleton.getBoolean(CookieConstants.GlobalAudioVolume, false);
			boolean isMute=UserInfoSingleton.getBoolean(CookieConstants.GlobalAudioStatus, false);
			int volume=0;
			if(!isMute){
				if(isSet){
					volume=UserInfoSingleton.getInt(CookieConstants.AudioVolume, 50);
				}{
					volume=live_volume;
					UserInfoSingleton.putIntAndCommit(CookieConstants.AudioVolume,volume);
				}
			}
			mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
					volume * max / 100, 0);
			live_url=GlobalParamInfo.getInstance().getLive_url();
			surfaceView.setVideoPath("udp://@"+live_url);
//			surfaceView.setVideoPath("/sata/media/killman.net.720p.mkv");
			check();
			

			
		}catch(Exception e){
			LogUtil.e(TAG, "startPlay fund error ",e);
		}
	
	}
	Thread myThread=null;
	Runnable runnable = new Runnable() { 
        @Override 
        public void run() { 
        	while(true){
        		if(isStop){
        			stopPlayback();
        			myThread=null;
        			isStop=false;
        			ViewManager.getInstance().getlVideo().setVisibility(View.VISIBLE);
    				ViewManager.getInstance().getVideoInfo().startPlay();
        			break;
        		}
        		try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
        	}
        } 
    }; 
	public void play(){
		surfaceView.play();
		check();
	}
	
	public void check(){
		if(isStop)return;
		if(live_url.startsWith("239")||live_url.startsWith("238")){
			//打开组播监听UDP
			mHandler.sendEmptyMessageDelayed(CMD_OPEN_UDP,7000);
			//检测组播监听是否组播正常
			mHandler.sendEmptyMessageDelayed(CMD_CHECK_UDP,10000);	
		}
			
	
	}
	/**
	 * 关闭检测组播是否正常的线程<br>
	 * 2014-1-15 上午10:39:35
	 *
	 */
	public void closeReceiveThread(){
		try{
			if(receiveThread!=null){
				receiveThread.interrupt();
				try {
					receiveThread.join(3000);
				} catch (InterruptedException e) {
					 LogUtil.e(TAG, "InterruptedException",e);
				}
				receiveThread=null;
			}
		}catch(Exception e){
			LogUtil.e(TAG, "closeReceiveThread fund error ",e);
		}
		
	}
	

	boolean isHasData=false;
	/**
	 * 检测直播是否正常<br>
	 * 2013-11-28 下午3:12:49
	 *
	 */
	public void checkUdp(){
		
		closeReceiveThread();
		
		receiveThread=new Thread(new Runnable() {
			@Override
			public void run() {
				MulticastSocket dataSocket=null;
				DatagramPacket dataPacket=null;
				try {
					if(null==live_url)return;
					 String [] urls=live_url.split(":");
					 if(urls.length<2)return;
					 InetAddress address =InetAddress.getByName(urls[0]);
					 dataSocket = new MulticastSocket(Integer.parseInt(urls[1]));
					 dataSocket.joinGroup(address);
					 byte[] receiveByte = new byte[2048];
					 dataPacket = new DatagramPacket(receiveByte, receiveByte.length);
					 LogUtil.i(TAG, "UDP服务启动...");
					 int size = 0;
					 while(!receiveThread.isInterrupted()){
						 // 无数据，则循环
						 if(size==0){
							 isHasData=false;
							 dataSocket.receive(dataPacket);
							 size = dataPacket.getLength();
//							 LogUtil.i(TAG, "收到数据 size="+size);
				              if (size > 0) {
				            	  isHasData=true;
				            	  size = 0;// 循环接收
				              }else{
				            	  LogUtil.i(TAG, "TS流停止发送数据");
				              }
				              Thread.sleep(50); 
						 }
					 }
				
				}
				catch(InterruptedException e){
	            	  LogUtil.e(TAG, "InterruptedException",e);
	             } 
				catch (Exception e) {
					LogUtil.e(TAG, "出现异常",e);
				} finally {
					
					if (dataSocket != null) {
						try {
							dataSocket.close();
						} catch (Exception e) {
							LogUtil.e(TAG, "出现异常2",e);
						}
					}
				}
			}
		});
		
		receiveThread.start();
	}
	
	/**
	 * 检测直播是否正常<br>
	 * 2013-11-28 下午3:12:49
	 *
	 */
	public void checkSingleUdp(){
		
		closeReceiveThread();
		
		receiveThread=new Thread(new Runnable() {
			@Override
			public void run() {
				DatagramSocket dataSocket=null;
				DatagramPacket dataPacket=null;
				try {
					if(null==live_url)return;
					 String [] urls=live_url.split(":");
					 if(urls.length<2)return;
					 InetAddress address =InetAddress.getByName(urls[0]);
					 dataSocket = new DatagramSocket(Integer.parseInt(urls[1]),address);
					 byte[] receiveByte = new byte[2048];
					 dataPacket = new DatagramPacket(receiveByte, receiveByte.length);
					 LogUtil.i(TAG, "UDP服务启动...");
					 int size = 0;
					 while(!receiveThread.isInterrupted()){
						 // 无数据，则循环
						 if(size==0){
							 isHasData=false;
							 dataSocket.receive(dataPacket);
							 size = dataPacket.getLength();
//							 LogUtil.i(TAG, "收到数据 size="+size);
				              if (size > 0) {
				            	  isHasData=true;
				            	  size = 0;// 循环接收
				              }else{
				            	  LogUtil.i(TAG, "TS流停止发送数据");
				              }
				              Thread.sleep(50); 
						 }
					 }
				
				}
				catch(InterruptedException e){
	            	  LogUtil.e(TAG, "InterruptedException",e);
	             } 
				catch (Exception e) {
					LogUtil.e(TAG, "出现异常",e);
				} finally {
					
					if (dataSocket != null) {
						try {
							dataSocket.close();
						} catch (Exception e) {
							LogUtil.e(TAG, "出现异常2",e);
						}
					}
				}
			}
		});
		
		receiveThread.start();
	}
	
	private final Handler mHandler=new MainHandler(this); 
	
	 private static class MainHandler extends WeakHandler<VideoSurfaceInfo> {
		 int countFail=0;	
		 boolean isLocal=false;
		 public MainHandler(VideoSurfaceInfo owner) {
	            super(owner);
	        }
	        @Override
			public void handleMessage(Message msg) {
	         
	        	VideoSurfaceInfo info = getOwner();
	        	if(info == null) return;
	        	LogUtil.i(TAG, "接收CMD"+msg.what);
				switch(msg.what){
				case CMD_OPEN_UDP:
					info.checkUdp();
					break;
				case CMD_CHECK_UDP:
					
					String isLive=UserInfoSingleton.getIslive();
					if(isLive.equals(ConstantValue.PLAY_LIVE)){
						boolean flag3=info.isHasData;
						LogUtil.i(TAG, "检测直播"+flag3);
						if(!flag3){
							countFail++;
							if(countFail>=6){
								if(!isLocal){
									isLocal=true;
									LogUtil.e(TAG, "直播中断,播放本地");
									//播放本地
									info.sendStart(RecvBase.CMD_CONTROL_PLAYLOCAL_L);
								}
							}
							
						}else{
							countFail=0;
							if(isLocal){
								isLocal=false;
								//播放直播
								LogUtil.e(TAG, "直播恢复,播放直播");
								info.sendStart(RecvBase.CMD_CONTROL_PLAYSTREAM_Z);
							}
						}
						info.mHandler.sendEmptyMessageDelayed(CMD_CHECK_UDP, 1000);
					}

					
					
					break;
				}
	        	super.handleMessage(msg);
			}
	 }
	 
	 private void sendStart(short cmd){
		  Intent mIntent = new Intent(RecvBase.ACTION_CMD_CONTROL);
		  mIntent.putExtra("cmd",cmd);
		  //发送广播
		  mContext.sendBroadcast(mIntent);
	  }
	
	 private static class PlayLiveThread extends Thread{
		public boolean isLive=false;
	
		private PlayLiveThread(boolean isLive) {
			super();
			this.isLive = isLive;
		}

		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if(isLive){
				ViewManager.getInstance().getSurfaceView().setVisibility(View.VISIBLE);
				ViewManager.getInstance().getSurfaceView().play();
			}else{
				ViewManager.getInstance().getSurfaceView().setVisibility(View.GONE);
				ViewManager.getInstance().getSurfaceView().pause();
			}
			
		}
		 
	 }
	 
	
	 private static class PlayLocalThread extends Thread{
		 public boolean isLocal=false;
		 
		private PlayLocalThread(boolean isLocal) {
			super();
			this.isLocal = isLocal;
		}

		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if(isLocal){
				ViewManager.getInstance().getlVideo().setVisibility(View.VISIBLE);
				ViewManager.getInstance().getVideoInfo().startPlay();
			}else{
				ViewManager.getInstance().getlVideo().setVisibility(View.GONE);
				ViewManager.getInstance().getlVideo().stopPlayback();
			}
		}
		 
	 }
	 /**
		 * 关闭直播<br>
		 * 2014-8-11 下午12:35:43
		 *
		 */
		public void stopPlayback(){
			try {
				onPause();
//				Thread.sleep(1000);
				onStop();
//				Thread.sleep(1000);
				onDestroy();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
		
		public void onPause(){
			surfaceView.onPause();
		}
		
		public void onStop(){
			surfaceView.onStop();
		}
		
		public void onDestroy(){
			surfaceView.onDestroy();
		}

	/**
	 * 初始化控件的位置
	 * 
	 * @param tv
	 *            被设置的控件
	 * @param pos
	 *            控件的位置
	 */
	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	void initPosition(View view, POS pos) {
		view.setX(pos.getLeft());
		view.setY(pos.getTop());
		view.setLayoutParams(new LayoutParams(pos.getWidth(), pos.getHeight()));
	}

	/**
	 * @return the isLive
	 */
	public boolean isLive() {
		return isLive;
	}
	/**
	 * @param isLive the isLive to set
	 */
	public void setLive(boolean isLive) {
		this.isLive = isLive;
	}
	/**
	 * @return the live_channel
	 */
	public String getLive_channel() {
		return live_channel;
	}
	/**
	 * @param live_channel the live_channel to set
	 */
	public void setLive_channel(String live_channel) {
		this.live_channel = live_channel;
	}
	/**
	 * @return the live_volume
	 */
	public int getLive_volume() {
		return live_volume;
	}
	/**
	 * @param live_volume the live_volume to set
	 */
	public void setLive_volume(int live_volume) {
		this.live_volume = live_volume;
	}
	/**
	 * @return the surfaceView
	 */
	public MVideoLive getSurfaceView() {
		return surfaceView;
	}

	/**
	 * @param surfaceView the surfaceView to set
	 */
	public void setSurfaceView(MVideoLive surfaceView) {
		this.surfaceView = surfaceView;
	}
	
	
}
